package com.yb.xczx.cloud.content.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yb.core.enums.RedisConstantEnum;
import com.yb.core.enums.HttpCode;
import com.yb.core.exception.XczxBusinessException;
import com.yb.xczx.cache.manager.api.XczxStringCacheManager;
import com.yb.xczx.cloud.content.entity.CourseCategory;
import com.yb.xczx.cloud.content.mapper.CourseCategoryMapper;
import com.yb.xczx.cloud.content.service.ICourseCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yb.xczx.cloud.content.vo.CourseCategoryTreeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程分类 服务实现类
 * </p>
 *
 * @author 姚兵
 * @since 2023-05-07
 */
@Service
@Slf4j
public class CourseCategoryServiceImpl extends ServiceImpl<CourseCategoryMapper, CourseCategory> implements ICourseCategoryService {

    @Autowired
    XczxStringCacheManager xczxStringCacheManager;
    @Override
    public List treeNodes() {
        Set<String> members = xczxStringCacheManager.getSet(RedisConstantEnum.Content.COURSE_CATEGORY.getKey(),String.class);
        if(!CollectionUtils.isEmpty(members)){
            log.info("命中缓存treeNodes");
            List<CourseCategoryTreeVo> treeVos=new ArrayList<>(members.size());
            members.stream().forEach(item->treeVos.add(JSONObject.parseObject(item,CourseCategoryTreeVo.class)));
            return treeVos;
        }

        log.info("缓存中不存在，从数据库中查询");
        List<CourseCategory> categoryList = this.list();
        List<CourseCategoryTreeVo> treeVos=new ArrayList<>();
        categoryList.stream().forEach(item->{
            CourseCategoryTreeVo rootVo = new CourseCategoryTreeVo();
            BeanUtils.copyProperties(item,rootVo);
            treeVos.add(rootVo);
        });


        treeVos.stream().forEach(item->treeify3(item,treeVos));
        List<CourseCategoryTreeVo> result = treeVos.stream().filter(item -> item.getParentid().equals("1")).collect(Collectors.toList());
        this.saveTreeToRedis(result);
        return result;
    }


    @Override
    public Map<String, CourseCategory> getByMtSt(String mt, String st) {
        LambdaQueryWrapper<CourseCategory> queryWrapper = new LambdaQueryWrapper<CourseCategory>().in(CourseCategory::getId, Arrays.asList(mt, st));
        List<CourseCategory> list = this.list(queryWrapper);
        if(list==null||list.size()<2){
            throw new XczxBusinessException(HttpCode.Response.BAD_REQUEST);
        }
        Map<String, CourseCategory> result = list.stream().collect(Collectors.toMap(item -> item.getId(), item -> item, (item1, item2) -> item2));
        return result;
    }

    @Override
    public void saveTreeToRedis(List<CourseCategoryTreeVo> courseCategoryTreeVos) {
        try {
            log.info("courseCategoryTreeVos:{}",courseCategoryTreeVos);

            xczxStringCacheManager.setSet(RedisConstantEnum.Content.COURSE_CATEGORY.getKey(),new HashSet<>(courseCategoryTreeVos));
        }catch (Exception e){
            log.info("e:{}",e);
        }

        log.info("插入完成");
    }

    //一下三种实现方式
    private void treeify3(CourseCategoryTreeVo parent,List<CourseCategoryTreeVo> treeVos){
        String parentId = parent.getId();
        Set<CourseCategoryTreeVo> childList = treeVos.stream().filter(item -> item.getParentid().equals(parentId)).collect(Collectors.toSet());
        parent.setChildrenTreeNodes(CollectionUtils.isEmpty(childList)?null:childList);
    }

    private List<CourseCategoryTreeVo> treeify(List<CourseCategoryTreeVo> treeVos){
        Map<String, CourseCategoryTreeVo> origin = new HashMap<>();
        Map<String, CourseCategoryTreeVo> dest = new HashMap<>();

        treeVos.forEach(item->{
            if(!item.getParentid().equals("0")) {
                origin.put(item.getId(), item);
                dest.put(item.getId(), item);
            }
        });

        treeVos.stream().forEach(item->{
            CourseCategoryTreeVo parent = origin.get(item.getParentid());
            if(Objects.nonNull(parent)){
                Set<CourseCategoryTreeVo> childrenTreeNodes = parent.getChildrenTreeNodes();
                if(Objects.isNull(childrenTreeNodes)){
                    childrenTreeNodes=new HashSet<>();
                    parent.setChildrenTreeNodes(childrenTreeNodes);
                }
                childrenTreeNodes.add(item);
                dest.remove(item.getId());
            }
        });
        log.info("dest:{}",dest);
        List<CourseCategoryTreeVo> resultList = dest.values().stream().collect(Collectors.toList());
        log.info("resultList:{}",resultList);
        return resultList;
    }

    public List<CourseCategoryTreeVo> treeify2(List<CourseCategoryTreeVo> treeVos){

        Map<String, List<CourseCategoryTreeVo>> parentIdMap = treeVos.stream().filter(Objects::nonNull)
                .filter(item -> !item.getParentid().equals("0"))
                .collect(Collectors.groupingBy(CourseCategoryTreeVo::getParentid));
        log.info("{}",parentIdMap);
        treeVos.stream().forEach(item->{
            List<CourseCategoryTreeVo> childList = parentIdMap.get(item.getId());
            if(Objects.nonNull(childList))
                item.setChildrenTreeNodes(new HashSet<>(childList));
        });
        log.info("treeVos:{}",treeVos);
        List<CourseCategoryTreeVo> collect = treeVos.stream().filter(item -> item.getParentid().equals("1")).collect(Collectors.toList());
        log.info("collect:{}",collect);
        return collect;
    }
}
